package homegraph

import (
	"bytes"
	"context"
	"encoding/json"
	"errors"
	"go.uber.org/zap"
	"io/ioutil"
	"log"
	"mall-portalv2/global"
	"net/http"
	"strings"

	"golang.org/x/oauth2/google"
)

//apiendpoint = "https://homegraph.googleapis.com/v1/"
//apiscope = "https://www.googleapis.com/auth/homegraph"
//skillcredentialsjsonfile = "./dataStore/mydream00.json"

const (
	ApiScope    = "https://www.googleapis.com/auth/homegraph"
	ApiEndpoint = "https://homegraph.googleapis.com/v1/"
)

// curl -X POST -H "Authorization: Bearer ACCESS_TOKEN" \
//   -H "Content-Type: application/json" \
//   -d @request-body.json \
//   "https://homegraph.googleapis.com/v1/devices:reportStateAndNotification"

// request-body.json:
// {
//   "requestId": "123ABC",
//   "agentUserId": "user-123",
//   "payload": {
//     "devices": {
//       "states": {
//         "light-123": {
//           "on": true
//         }
//       }
//     }
//   }
// }

type Response struct {
	Error struct {
		Code    int    `json:"code"`
		Message string `json:"message"`
		Status  string `json:"status"`
	} `json:"ctx"`
}

func Dial(credentialsJsonFile string) (Client, error) {

	data, err := ioutil.ReadFile(credentialsJsonFile)
	if err != nil {
		return Client{}, err
	}

	conf, err := google.JWTConfigFromJSON(data, ApiScope)
	if err != nil {
		return Client{}, err
	}

	return Client{httpClient: conf.Client(context.Background())}, nil
}

type Client struct {
	httpClient *http.Client
}

func (c Client) RequestResync(agentUserId string) error {
	res, err := c.httpClient.Post(
		ApiEndpoint+"devices:requestSync",
		"application/json",
		strings.NewReader(`{"agentUserId": "`+agentUserId+`", "async":false}`),
	)
	if err != nil {
		return err
	}

	var response Response
	if err := json.NewDecoder(res.Body).Decode(&response); err != nil {
		return err
	}

	if err := res.Body.Close(); err != nil {
		return err
	}

	if response.Error.Code != 0 {
		return errors.New(response.Error.Message)
	}

	return nil
}

type SyncData struct {
	AgentUserId string `json:"agentUserId"`
	Async       bool   `json:"async"`
}

func (c Client) RequestResync2(data SyncData) error {
	body, _ := json.Marshal(data)
	a := bytes.NewReader(body)

	var res *http.Response
	var req *http.Request
	//ApiEndpoint+"devices:requestSync"
	test := "https://homegraph.googleapis.com/v1/devices:requestSync"
	req, err := http.NewRequest("POST", test, a)
	if err != nil {
		global.Log.Info("reuqest json err", zap.Error(err))
		return err
	}
	res, err = c.httpClient.Do(req)
	if err != nil {
		global.Log.Info("reuqest do err", zap.Error(err))
		return err
	}

	defer res.Body.Close()
	body, err = ioutil.ReadAll(res.Body)

	if err != nil {
		global.Log.Info("reuqest err", zap.Error(err))
		return err
	}

	global.Log.Info("打印结果", zap.Any("reqBody", string(body)))

	return nil
}

type State struct {
	AgentUserId string      `json:"agentUserId"`
	RequestId   string      `json:"requestId"`
	Payload     interface{} `json:"payload"`
}

func (c Client) ReportState(state *State) (int, error) {
	body, _ := json.Marshal(state)

	res, err := c.httpClient.Post(
		ApiEndpoint+"devices:reportStateAndNotification",
		"application/json",
		bytes.NewReader(body),
	)
	if err != nil {
		log.Println("ERR REs:")
		return 0, err
	}

	var response Response
	if err := json.NewDecoder(res.Body).Decode(&response); err != nil {
		return 0, err
	}

	if err := res.Body.Close(); err != nil {
		return 0, err
	}

	if response.Error.Code != 0 {
		return response.Error.Code, errors.New(response.Error.Message)
	}

	return 0, nil
}
